// Copyright (c) 2025 Yao Yu
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use ostd::task::{Task, TaskOptions};
use ostd::prelude::*;
use alloc::{sync::Arc, vec::Vec};
use crate::{
    thread::{*, tasks::*},
    process::Process,
};

pub struct KernelInfo{
    pub files: Vec<&'static [u8]>,
}

fn thread_fn() {
    let current = Task::current().unwrap();
    let current_thread = current.as_thread().unwrap();
    let kernel_data_pointer = current_thread.data().unwrap();
    let kernel_data = kernel_data_pointer.downcast_ref::<KernelInfo>().unwrap();
    let mut pid: u64 = 0;
    for file in &kernel_data.files {
        pid += 1;
        let (vm_space, user_ctx) = create_vm_space(file).unwrap();
        let process = Process::new(pid, vm_space);
        let user_task = Arc::new_cyclic(|weak_task| {
            let thread = Arc::new(Thread::new(weak_task.clone(), None));
            let root_vmar1 = process.get_root_vmar().clone();
            let thread_local = ThreadLocal::new(root_vmar1);
            create_user_task(thread, Arc::new(user_ctx), thread_local)
        });
        let thread11 = user_task.as_thread().unwrap();
        process.create_thread(Arc::clone(&user_task));
        thread11.run();
    }
    println!("kernel thread end");
}

pub fn create_init_thread(thread_ref: Arc<Thread>) -> Task {
    TaskOptions::new(thread_fn)
    .data(thread_ref)
    .build()
    .unwrap()
}